package com.ccteam.fluidmusic.ui.user

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.ccteam.fluidmusic.NavLoginDirections
import com.ccteam.fluidmusic.NavPlaylistSheetListDirections
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentMeBinding
import com.ccteam.fluidmusic.databinding.MeHomeInfoItemBinding
import com.ccteam.fluidmusic.databinding.MeHomeNotLoginItemBinding
import com.ccteam.fluidmusic.utils.TransitionUtils
import com.ccteam.fluidmusic.view.adapters.ViewBindViewHolder
import com.ccteam.fluidmusic.view.adapters.toolbar.ToolbarTitleAdapter
import com.ccteam.fluidmusic.view.adapters.viewbinding.MultiTypeViewBindingAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.ui.user.SelfInformationFragment.Companion.RESULT_USER_INFO_KEY
import com.ccteam.shared.result.BaseItemData
import com.ccteam.shared.result.BaseItemData.Companion.LAYOUT_ME_INFO_ITEM
import com.ccteam.shared.result.title.ToolbarTitleItem
import com.ccteam.shared.result.user.MeHomeInfoItem
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.inject.Inject


@AndroidEntryPoint
class MeFragment : Fragment() {

    private var _binding: FragmentMeBinding? = null
    private val binding get() = _binding!!

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    private val meViewModel by viewModels<MeViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setFragmentResultListener(RESULT_USER_INFO_KEY,listener = { _,bundle ->
            if(bundle.getBoolean(RESULT_USER_INFO_KEY)){
                viewLifecycleOwner.lifecycleScope.launch {
                    meViewModel.refreshUserInfo()
                }
            }
        })

        enterTransition = TransitionUtils.enterScale
        exitTransition = TransitionUtils.exitScale
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentMeBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val titleAdapter = ToolbarTitleAdapter()
        titleAdapter.submitList(mutableListOf(ToolbarTitleItem(getString(R.string.me_name_info))))

        lightBounceEdgeEffectFactory.applyBounceView(binding.rvMeHome,this)
        binding.rvMeHome.edgeEffectFactory = lightBounceEdgeEffectFactory

        val dataAdapter = MeHomeRVAdapter(callback)

        binding.rvMeHome.adapter = ConcatAdapter(titleAdapter,dataAdapter)

        meViewModel.meHomeList.observe(viewLifecycleOwner, {
            dataAdapter.submitList(it)
        })

        binding.refreshView.setOnRefreshListener {
            viewLifecycleOwner.lifecycleScope.launch {
                meViewModel.refreshUserInfo()
            }
        }

        meViewModel.loadMessage.observe(viewLifecycleOwner, {
            binding.refreshView.isRefreshing = it is LoadMessage.Loading
            binding.statusView.changeToErrorStatus(it)
            binding.statusView.changeToLoadingStatus(it is LoadMessage.Loading)
        })

        binding.statusView.setRetryClickListener {
            viewLifecycleOwner.lifecycleScope.launch {
                meViewModel.refreshUserInfo()
            }
        }

        binding.toolbarMeHome.setOnMenuItemClickListener { menuItem ->
            return@setOnMenuItemClickListener when(menuItem.itemId){
                R.id.toolbar_me_settings ->{
                    findNavController().navigate(MeFragmentDirections.actionMeFragmentToSettingActivity())
                    true
                }
                else ->
                    false
            }
        }

    }

    private val callback = object: MeHomeItemCallback {

        override fun loginClicked() {
            findNavController().navigate(
                NavLoginDirections.actionGlobalLoginFragment()
            )
        }

        override fun momentsListClicked(item: MeHomeInfoItem) {
            findNavController().navigate(
                MeFragmentDirections.actionMeFragmentToUserMomentsFragment(
                    item
                )
            )
        }

        override fun playlistSheetListClicked(item: MeHomeInfoItem) {
            findNavController().navigate(NavPlaylistSheetListDirections.actionGlobalPlaylistSheetListFragment(
                item.userId
            ))
        }

        override fun editUserInfoClicked(item: MeHomeInfoItem) {
            findNavController().navigate(
                MeFragmentDirections.actionMeFragmentToSelfInformationFragment(
                    item.userId
                )
            )
        }

    }

    class MeHomeRVAdapter(
        private val callback: MeHomeItemCallback
    ): MultiTypeViewBindingAdapter(MeHomeInfoItem.differCallback) {

        override fun createMultiViewBinding(
            parent: ViewGroup,
            viewType: Int
        ): RecyclerView.ViewHolder? {
            return when (viewType) {
                BaseItemData.LAYOUT_ME_HOME_NOT_LOGIN -> {
                    MeHomeNotLoginViewHolder(
                        MeHomeNotLoginItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
                    )
                }
                LAYOUT_ME_INFO_ITEM -> {
                    MeHomeUserInfoViewHolder(
                        MeHomeInfoItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
                    )
                }
                else -> {
                    null
                }
            }
        }

        override fun bindMultiItem(
            holder: RecyclerView.ViewHolder,
            position: Int,
            item: BaseItemData,
            payloads: MutableList<Any>,
            viewType: Int
        ) {
            if(viewType == LAYOUT_ME_INFO_ITEM){
                handleMeHomeInfo(holder as MeHomeUserInfoViewHolder,item as MeHomeInfoItem)
            }
        }

        private fun handleMeHomeInfo(holder: MeHomeUserInfoViewHolder, item: MeHomeInfoItem){
            holder.item = item
            holder.binding.tvMomentsNum.text = item.momentsCount.toString()
            holder.binding.tvAccountName.text = item.userName
            holder.binding.tvPlaylistSheetNum.text = item.playlistSheetCount.toString()
            holder.binding.tvAccountIntroduction.text = item.userIntroduction
            Glide.with(holder.binding.ivAccountImg)
                .load(item.userPhotoUrl)
                .placeholder(R.drawable.img_default_artist_small)
                .into(holder.binding.ivAccountImg)
        }

        inner class MeHomeNotLoginViewHolder(
            binding: MeHomeNotLoginItemBinding
        ):ViewBindViewHolder<MeHomeNotLoginItemBinding>(binding){

            init {
                binding.btnLogin.setOnClickListener {
                    callback.loginClicked()
                }
            }
        }

        inner class MeHomeUserInfoViewHolder(
            binding: MeHomeInfoItemBinding
        ):ViewBindViewHolder<MeHomeInfoItemBinding>(binding){

            var item: MeHomeInfoItem? = null

            init {
                binding.btnEditInfo.setOnClickListener {
                    item?.let { data ->
                        callback.editUserInfoClicked(data)
                    }
                }

                binding.cardViewPlaylistSheet.setOnClickListener {
                    item?.let { data ->
                        callback.playlistSheetListClicked(data)
                    }
                }

                binding.cardViewMoments.setOnClickListener {
                    item?.let { data ->
                        callback.momentsListClicked(data)
                    }
                }
            }
        }

    }

    interface MeHomeItemCallback{
        fun loginClicked()
        fun momentsListClicked(item: MeHomeInfoItem)
        fun playlistSheetListClicked(item: MeHomeInfoItem)
        fun editUserInfoClicked(item: MeHomeInfoItem)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}